home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume23 / log_tcp / part01 next >
Encoding:
Text File  |  1991-10-19  |  52.3 KB  |  1,618 lines

  1. Newsgroups: comp.sources.misc
  2. From: wietse@wzv.win.tue.nl (Wietse Venema)
  3. Subject:  v23i077:  log_tcp - Package to monitor TCP/UDP connections, Part01/01
  4. Message-ID: <1991Oct19.025711.14716@sparky.imd.sterling.com>
  5. X-Md4-Signature: d79ef38346de3a9405025bac38985df4
  6. Date: Sat, 19 Oct 1991 02:57:11 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: wietse@wzv.win.tue.nl (Wietse Venema)
  10. Posting-number: Volume 23, Issue 77
  11. Archive-name: log_tcp/part01
  12. Environment: UNIX
  13. Supersedes: log_tcp: Volume 20, Issue 8
  14.  
  15. This package provides a couple of tiny programs that log requests for
  16. internet services (examples: TFTP, EXEC, FTP, RSH, TELNET, RLOGIN,
  17. FINGER, SYSTAT). Optional features are: access control based on pattern
  18. matching, and protection against rsh and rlogin attacks from hosts that
  19. pretend to have someone elses host name.
  20.  
  21. The programs are nothing but small network daemon front ends. By
  22. default, they just log the remote host name and then invoke the real
  23. network daemon daemon, without requiring any changes to existing
  24. software or configuration files.
  25.  
  26. Enhancements over the previous release are: support for datagram (UDP
  27. and RPC) services, and execution of shell commands when a (remote host,
  28. requested service) pair matches a pattern in the access control tables.
  29.  
  30.     Wietse Venema (wietse@wzv.win.tue.nl),
  31.     Eindhoven University of Technology,
  32.     The Netherlands.
  33. ---
  34. #! /bin/sh
  35. # This is a shell archive.  Remove anything before this line, then feed it
  36. # into a shell via "sh file" or similar.  To overwrite existing files,
  37. # type "sh file -c".
  38. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  39. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  40. # Contents:  README BLURB Makefile fromhost.c hosts_access.5
  41. #   hosts_access.c log_tcp.h miscd.c refuse.c shell_cmd.c strcasecmp.c
  42. #   tcpd.c try.c
  43. # Wrapped by kent@sparky on Wed Oct 16 23:03:11 1991
  44. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  45. echo If this archive is complete, you will see the following message:
  46. echo '          "shar: End of archive 1 (of 1)."'
  47. if test -f 'README' -a "${1}" != "-c" ; then 
  48.   echo shar: Will not clobber existing file \"'README'\"
  49. else
  50.   echo shar: Extracting \"'README'\" \(8024 characters\)
  51.   sed "s/^X//" >'README' <<'END_OF_FILE'
  52. X@(#) README 1.6 91/10/04 21:28:09
  53. X
  54. XGeneral description
  55. X-------------------
  56. X
  57. XWith this package you can monitor connections to the SYSTAT, FINGER,
  58. XFTP, TELNET, RLOGIN, RSH, EXEC, TFTP, old and new TALK, and other IP
  59. Xnetwork services.  Connections are reported through the syslog daemon.
  60. XRequirements are that network daemons are started by the inetd program
  61. Xor something similar, and the availability of a syslog(3) library.
  62. X
  63. XThe programs are tiny front ends. By default, they just report the name
  64. Xof the remote host and of the requested service, and then invoke the
  65. Xreal network daemon; no information is exchanged with the remote client
  66. Xprocess. In the most common case, no changes should be required to
  67. Xexisting software or to existing configuration files.  Just move the
  68. Xvendor-provided daemons to another place and install the front ends
  69. Xinto their original places.  Installation details are given below.
  70. X
  71. XEarly versions of the programs were tested with Ultrix >= 2.2, with
  72. XSunOS >= 3.4 and ISC 2.2. Later versions have been installed on a wide
  73. Xvariety of platforms (BSD-style, SYSV-style, Apollo's idea of UNIX).
  74. X
  75. XThe present release was tested with SunOS 4.1.1, Ultrix 4.1 and Apollo
  76. XSR10.3.5, but it should still run without modification on top of most
  77. XBSD-style TCP/IP implementations.
  78. X
  79. XRestriction
  80. X-----------
  81. X
  82. XSome UDP (and RPC) daemons linger around for a while after they have
  83. Xfinished their work, just in case another request comes in.  Only the
  84. Xrequest that started such a daemon will be logged. This restriction
  85. Xdoes normally not apply to connection-oriented (TCP) services.
  86. X
  87. XAccess control
  88. X--------------
  89. X
  90. XWhen compiled with -DHOSTS_ACCESS, the front-end programs support a
  91. Xsimple form of access control that is based on pattern matching.  The
  92. Xaccess-control software provides hooks for the execution of shell
  93. Xcommands when a pattern fires.  For details, see the hosts_access(5)
  94. Xmanual page.
  95. X
  96. XDetection of hosts that pretend to have someone elses host name
  97. X---------------------------------------------------------------
  98. X
  99. XAuthentication based on host names, such as used by RLOGIN and RSH,
  100. Xused to work quite reliably when all host name lookups were done from
  101. Xthe local /etc/hosts file or its equivalent.
  102. X
  103. XWith _distributed_ name services, authentication schemes that rely on
  104. Xhost names can be subverted by playing games with the address->name
  105. Xmaps that are maintained by some far-away name server.  Many rshd and
  106. Xrlogind implementations still blindly believe the remote host name that
  107. Xthey get from gethostbyaddr() and don't bother to check if that host
  108. Xname really belongs to the system that they are talking to.
  109. X
  110. XThe front-end programs verify the remote host name that was returned by
  111. Xthe name server responsible for the address->name mapping, by looking
  112. Xat the host address that is returned by the name server responsible for
  113. Xthe name->address mapping of that host name. If the latter address does
  114. Xnot match the original host address, the front ends conclude that they
  115. Xare dealing with a host that pretends to have someone elses host name.
  116. X
  117. XIf the sources are compiled with -DPARANOID, the front ends will drop
  118. Xthe connection in case of a host name/address mismatch. Otherwise, the
  119. Xfront ends just ignore the bad host name and use the host address when
  120. Xconsulting the access control tables.
  121. X
  122. XRelated software
  123. X----------------
  124. X
  125. XVersions of rshd and rlogind, hacked to report the remote user name,
  126. Xare available for anonymous ftp (ftp.win.tue.nl:/pub/logdaemon.tar.Z).
  127. XThese programs are derived from BSD source; they have been tested only
  128. Xwith SunOS >= 4.0.
  129. X
  130. XAnother way to manage access to tcp/ip services is illustrated by the
  131. Xservers provided with the authutil package (comp.sources.unix volume
  132. X22). This has the advantage that one will get the remote username from
  133. Xany host supporting RFC 931 security.  By installing the auth package
  134. X(same volume) one supports RFC 931 security too (but you will have to
  135. Xbelieve what the remote host tells you).  Eventually one can start
  136. Xcutting off unauthenticated connections. This is obviously a much more
  137. Xadvanced approach than what my front-end programs provide. The present
  138. Xpackage is more suitable for those who lack the resources to install
  139. Xanything that requires more than just renaming a couple of executables.
  140. X
  141. XConfiguration and installation (the easy way)
  142. X---------------------------------------------
  143. X
  144. XAn advanced installation recipe is given lateron. The "easy way" recipe
  145. Xrequires no changes to existing software or configuration files.
  146. X
  147. XIf you don't run Ultrix, you don't need the miscd front-end program.
  148. XThe Ultrix miscd daemon implements among others the SYSTAT service,
  149. Xwhich pipes the output from the WHO command to standard output.
  150. X
  151. XBy default, the front-end programs assume that the vendor-provided
  152. Xdaemons will be moved to the "/usr/etc/..." directory.  If you want
  153. Xsomething else, adjust the REAL_DAEMON and the REAL_DAEMON_DIR macros
  154. Xin the files miscd.c and tcpd.c.
  155. X
  156. XFollow the instructions at the beginning of the Makefile and compile
  157. Xthe programs. The result is three binaries. The `try' program can be
  158. Xused to play with host access control tables. The tcpd and miscd
  159. Xprograms are the actual front end programs.
  160. X
  161. XThe tcpd program can be used for monitoring requests for the telnet,
  162. Xfinger, ftp, exec, rsh, rlogin, tftp, talk, spray, rusers, comsat and
  163. Xother services that have a one-to-one mapping onto executable files.
  164. X
  165. XDecide which services you want to be monitored. Move the corresponding
  166. Xvendor-provided daemon programs to the location specified by the
  167. XREAL_DAEMON_DIR macro in the file tcpd.c, and copy the tcpd front end
  168. Xto the locations where the vendor-provided daemons used to be. That is,
  169. Xone copy of (or link to) the tcpd program for each service that you
  170. Xwant to monitor.
  171. X
  172. XUltrix only: if you want to monitor connections to the SYSTAT service,
  173. Xmove the vendor-provided miscd daemon to the location specified by the
  174. XREAL_DAEMON macro in the miscd.c file, and install the miscd front end
  175. Xinto the original miscd location.
  176. X
  177. XConfiguration and installation (the advanced way)
  178. X-------------------------------------------------
  179. X
  180. XInstead of moving the vendor-provided daemons to another directory,
  181. Xdefine the REAL_DAEMON_DIR to reflect the present location of those
  182. Xdaemons, and install the tcpd command in the same directory (Apollo
  183. XUNIX users will want to install the front end under a different name
  184. Xbecause tcpd is the name of an already existing command. A suitable
  185. Xname for the front-end program would be "frontd"). Then perform the
  186. Xfollowing edits on the inetd configuration file (usually located in
  187. X/etc/inetd.conf):
  188. X
  189. X    finger  stream  tcp     nowait  nobody  /usr/etc/in.fingerd     in.fingerd
  190. X
  191. Xbecomes:
  192. X
  193. X    finger  stream  tcp     nowait  nobody  /usr/etc/tcpd           in.fingerd
  194. X
  195. X(the example applies to SunOS 4.x; other UNIX implementations should
  196. Xnot differ much). Similar changes will be needed for the other services
  197. Xthat are to be covered by the tcpd (or frontd) front-end program. Send
  198. Xa SIGHUP to the inetd process to make the changes effective.
  199. X
  200. XThe same trick can be played with the Ultrix miscd daemon but then
  201. Xeither the miscd daemon front end or the real miscd daemon will have to
  202. Xbe given a different name.
  203. X
  204. XAcknowledgements
  205. X----------------
  206. X
  207. XThanks to Brendan Kehoe (brendan@cs.widener.edu), Heimir Sverrisson
  208. X(heimir@hafro.is) and Dan Bernstein (brnstnd@kramden.acf.nyu.edu) for
  209. Xfeedback on an early release of this product.  The host name/address
  210. Xcheck was suggested by John Kimball (jkimball@src.honeywell.com).
  211. XWillem-Jan Withagen (wjw@eb.ele.tue.nl), Pieter Schoenmakers
  212. X(tiggr@es.ele.tue.nl) and Charles S. Fuller (fuller@wccs.psc.edu)
  213. Xprovided help on dealing with with Apollo's UNIX environment.  Hal R.
  214. XBrand (BRAND@addvax.llnl.gov) told me how to get the remote IP address
  215. Xin case of datagram-oriented services, and suggested the optional shell
  216. Xcommand feature.
  217. X
  218. X    Wietse Venema (wietse@wzv.win.tue.nl),
  219. X    Mathematics and Computing Science,
  220. X    Eindhoven University of Technology,
  221. X    The Netherlands.
  222. END_OF_FILE
  223.   if test 8024 -ne `wc -c <'README'`; then
  224.     echo shar: \"'README'\" unpacked with wrong size!
  225.   fi
  226.   # end of 'README'
  227. fi
  228. if test -f 'BLURB' -a "${1}" != "-c" ; then 
  229.   echo shar: Will not clobber existing file \"'BLURB'\"
  230. else
  231.   echo shar: Extracting \"'BLURB'\" \(1180 characters\)
  232.   sed "s/^X//" >'BLURB' <<'END_OF_FILE'
  233. X@(#) BLURB 1.4 91/10/02 23:02:02
  234. X
  235. XThis package provides a couple of tiny programs that log requests for
  236. Xinternet services (examples: TFTP, EXEC, FTP, RSH, TELNET, RLOGIN,
  237. XFINGER, SYSTAT). Optional features are: access control based on pattern
  238. Xmatching, and protection against rsh and rlogin attacks from hosts that
  239. Xpretend to have someone elses host name.
  240. X
  241. XThe programs are nothing but small network daemon front ends. By
  242. Xdefault, they just log the remote host name and then invoke the real
  243. Xnetwork daemon daemon, without requiring any changes to existing
  244. Xsoftware or configuration files.
  245. X
  246. XConnections are reported through the syslog(3) facility. Each record
  247. Xcontains a time stamp, the remote host name and the name of the service
  248. Xrequested. The information can be useful to detect unwanted activities,
  249. Xespecially when logfile information from several hosts is merged.
  250. X
  251. XEnhancements over the previous release are: support for datagram (UDP
  252. Xand RPC) services, and execution of shell commands when a (remote host,
  253. Xrequested service) pair matches a pattern in the access control tables.
  254. X
  255. X    Wietse Venema (wietse@wzv.win.tue.nl),
  256. X    Eindhoven University of Technology,
  257. X    The Netherlands.
  258. END_OF_FILE
  259.   if test 1180 -ne `wc -c <'BLURB'`; then
  260.     echo shar: \"'BLURB'\" unpacked with wrong size!
  261.   fi
  262.   # end of 'BLURB'
  263. fi
  264. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  265.   echo shar: Will not clobber existing file \"'Makefile'\"
  266. else
  267.   echo shar: Extracting \"'Makefile'\" \(3253 characters\)
  268.   sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  269. X# @(#) Makefile 1.4 91/10/04 21:28:11
  270. X
  271. X##############################
  272. X## Begin configuration options
  273. X
  274. X# By default, logfile entries are written to the same file as used for
  275. X# sendmail transaction logs. Change the definition of the following macro
  276. X# if you disagree. See /usr/include/syslog.h for examples. Some syslog
  277. X# versions do not provide this flexibility.
  278. X
  279. XFACILITY= LOG_MAIL
  280. X
  281. X# To disable host access control, comment out the following macro definition.
  282. X# Note: host access control requires the strtok() and strchr() routines.
  283. X
  284. XACCESS    = -DHOSTS_ACCESS
  285. X
  286. X# Disable the following macro definition if you wish to talk to hosts that
  287. X# pretend to have someone elses host name.
  288. X
  289. XPARANOID= -DPARANOID
  290. X
  291. X# If your system supports NIS or YP-style netgroups, enable the following
  292. X# macro definition.
  293. X
  294. XNETGROUP= -DNETGROUP
  295. X
  296. X# Some versions of apollo UNIX have a bug in the getpeername(2) routine.
  297. X# You have this bug if the front end reports that all UDP connections come
  298. X# from address 0.0.0.0. Compile with -DGETPEERNAME_BUG for a workaround.
  299. X
  300. XBUGS    = -DGETPEERNAME_BUG
  301. X
  302. X# Apollo Domain/OS offers both bsd and sys5 environments, sometimes
  303. X# on the same machine.  If your Apollo is primarily sys5.3 and also
  304. X# has bsd4.3, enable the following to build under bsd and run under
  305. X# either environment.
  306. X
  307. X#SYSTYPE=  -A run,any -A sys,any
  308. X
  309. X# If your C library does not have memcmp(3), compile with -Dmemcmp=bcmp.
  310. X
  311. XCFLAGS    = -O -DFACILITY=$(FACILITY) $(ACCESS) $(PARANOID) $(NETGROUP) \
  312. X    $(BUGS) $(SYSTYPE)
  313. X
  314. X# Include the file strcasecmp.o if it is not provided by your C library.
  315. X# The strcasecmp.c file provided with this package comes from BSD UNIX.
  316. X
  317. XAUX_OBJ    = # strcasecmp.o
  318. X
  319. X# Some System-V versions require that you explicitly specify the networking
  320. X# libraries (for example, -lnet or -linet).
  321. X
  322. XLIBS    = # -lnet
  323. X
  324. X## End configuration options
  325. X############################
  326. X
  327. XTCPD_OBJ= tcpd.o fromhost.o hosts_access.o shell_cmd.o refuse.o
  328. XMISC_OBJ= miscd.o fromhost.o hosts_access.o shell_cmd.o refuse.o
  329. XTRY_OBJ    = try.o hosts_access.o shell_cmd.o
  330. X
  331. XKIT    = README miscd.c tcpd.c fromhost.c hosts_access.c shell_cmd.c \
  332. X    refuse.c log_tcp.h try.c Makefile hosts_access.5 strcasecmp.c BLURB
  333. X
  334. Xall:    tcpd miscd try
  335. X
  336. Xtcpd:    $(TCPD_OBJ) $(AUX_OBJ)
  337. X    $(CC) $(CFLAGS) -o $@ $(TCPD_OBJ) $(AUX_OBJ) $(LIBS)
  338. X
  339. Xmiscd:    $(MISC_OBJ) $(AUX_OBJ)
  340. X    $(CC) $(CFLAGS) -o $@ $(MISC_OBJ) $(AUX_OBJ) $(LIBS)
  341. X
  342. Xtry:    $(TRY_OBJ) $(AUX_OBJ)
  343. X    $(CC) $(CFLAGS) -o $@ $(TRY_OBJ) $(AUX_OBJ)
  344. X
  345. Xfromhost: fromhost.c
  346. X    $(CC) $(CFLAGS) -DTEST -o fromhost fromhost.c
  347. X    rm -f fromhost.o
  348. X
  349. Xshar:    
  350. X    @shar $(KIT)
  351. X
  352. Xarchive:
  353. X    $(ARCHIVE) $(KIT)
  354. X
  355. Xclean:
  356. X    rm -f tcpd miscd try fromhost *.o core
  357. X
  358. X# Enable all bells and whistles for linting.
  359. X
  360. Xlint:
  361. X    lint -DFACILITY=LOG_MAIL -DHOSTS_ACCESS -DPARANOID -DNETGROUP \
  362. X    -DGETPEERNAME_BUG tcpd.c fromhost.c hosts_access.c shell_cmd.c refuse.c
  363. X    lint -DFACILITY=LOG_MAIL -DHOSTS_ACCESS -DPARANOID -DNETGROUP \
  364. X    -DGETPEERNAME_BUG miscd.c fromhost.c hosts_access.c shell_cmd.c refuse.c
  365. X
  366. X# Compilation dependencies.
  367. X
  368. Xfromhost.o : fromhost.c log_tcp.h Makefile
  369. Xhosts_access.o : hosts_access.c Makefile
  370. Xmiscd.o : miscd.c log_tcp.h Makefile
  371. Xrefuse.o : refuse.c log_tcp.h
  372. Xshell_cmd.o : shell_cmd.c Makefile
  373. Xstrcasecmp.o : strcasecmp.c 
  374. Xtcpd.o : tcpd.c log_tcp.h Makefile
  375. Xtry.o : try.c Makefile
  376. END_OF_FILE
  377.   if test 3253 -ne `wc -c <'Makefile'`; then
  378.     echo shar: \"'Makefile'\" unpacked with wrong size!
  379.   fi
  380.   # end of 'Makefile'
  381. fi
  382. if test -f 'fromhost.c' -a "${1}" != "-c" ; then 
  383.   echo shar: Will not clobber existing file \"'fromhost.c'\"
  384. else
  385.   echo shar: Extracting \"'fromhost.c'\" \(5501 characters\)
  386.   sed "s/^X//" >'fromhost.c' <<'END_OF_FILE'
  387. X /*
  388. X  * fromhost() returns the type of connection (datagram, stream) and the name
  389. X  * of the host at the other end of standard input (the host address if host
  390. X  * name lookup fails, "stdin" if it is connected to a terminal, or "unknown"
  391. X  * in all other cases). The return status is (-1) if the remote host
  392. X  * pretends to have someone elses host name, otherwise a zero status is
  393. X  * returned.
  394. X  * 
  395. X  * Diagnostics are reported through syslog(3).
  396. X  * 
  397. X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  398. X  */
  399. X
  400. X#ifndef lint
  401. Xstatic char sccsid[] = "@(#) fromhost.c 1.4 91/10/02 23:01:46";
  402. X#endif
  403. X
  404. X/* System libraries. */
  405. X
  406. X#include <sys/types.h>
  407. X#include <sys/param.h>
  408. X#include <sys/socket.h>
  409. X#include <netinet/in.h>
  410. X#include <netdb.h>
  411. X#include <stdio.h>
  412. X#include <syslog.h>
  413. X#include <errno.h>
  414. X
  415. Xextern char *inet_ntoa();
  416. Xextern char *strncpy();
  417. Xextern char *strcpy();
  418. X
  419. X/* Local stuff. */
  420. X
  421. X#include "log_tcp.h"
  422. X
  423. X/* Forward declarations. */
  424. X
  425. Xstatic int matchname();
  426. X
  427. X/* The following are to be used in assignment context, not in comparisons. */
  428. X
  429. X#define    GOOD    1
  430. X#define    BAD    0
  431. X
  432. X /*
  433. X  * The apollo sr10.3 getpeername(2) does not return an error in case of a
  434. X  * datagram-oriented socket. Instead, it claims that all UDP or RPC requests
  435. X  * come from address 0.0.0.0. The following code works around the problem.
  436. X  */
  437. X
  438. X#ifdef GETPEERNAME_BUG
  439. X
  440. Xstatic int fix_getpeername(sock, sa, len)
  441. Xint     sock;
  442. Xstruct sockaddr *sa;
  443. Xint    *len;
  444. X{
  445. X    int     ret;
  446. X    struct sockaddr_in *sin = (struct sockaddr_in *) sa;
  447. X
  448. X    if ((ret = getpeername(sock, sa, len)) >= 0
  449. X    && sa->sa_family == AF_INET
  450. X    && strcmp(inet_ntoa(sin->sin_addr), "0.0.0.0") == 0) {
  451. X    errno = ENOTCONN;
  452. X    return (-1);
  453. X    } else {
  454. X    return (ret);
  455. X    }
  456. X}
  457. X
  458. X#define    getpeername    fix_getpeername
  459. X#endif
  460. X
  461. X/* fromhost - find out what is at the other end of standard input */
  462. X
  463. Xint     fromhost(f)
  464. Xstruct from_host *f;
  465. X{
  466. X    struct sockaddr sa;
  467. X    struct sockaddr_in *sin = (struct sockaddr_in *) (&sa);
  468. X    struct hostent *hp;
  469. X    int     length = sizeof(sa);
  470. X    char    buf[BUFSIZ];
  471. X
  472. X    /*
  473. X     * Look up the remote host address. Hal R. Brand <BRAND@addvax.llnl.gov>
  474. X     * suggested how to get the remote host info in case of UDP connections:
  475. X     * peek at the first message without actually looking at its contents.
  476. X     */
  477. X
  478. X#define    punt(name) { f->sock_type = 0; strcpy(f->source, name); return(0); }
  479. X
  480. X    if (getpeername(0, &sa, &length) >= 0) {    /* assume TCP request */
  481. X    f->sock_type = FROM_CONNECTED;
  482. X    } else {
  483. X    switch (errno) {
  484. X    case ENOTSOCK:                /* stdin is not a socket */
  485. X        punt(isatty(0) ? "stdin" : "unknown");
  486. X    case ENOTCONN:                /* assume UDP request */
  487. X        if (recvfrom(0, buf, sizeof(buf), MSG_PEEK, &sa, &length) < 0) {
  488. X        syslog(LOG_ERR, "recvfrom: %m");
  489. X        punt("unknown");
  490. X        }
  491. X        f->sock_type = FROM_UNCONNECTED;
  492. X        break;
  493. X    default:                /* other, punt */
  494. X        syslog(LOG_ERR, "getpeername: %m");
  495. X        punt("unknown");
  496. X    }
  497. X    }
  498. X
  499. X    /*
  500. X     * Now that we have the remote host address, look up the remote host
  501. X     * name. Use the address if name lookup fails. At present, we can only
  502. X     * handle names or addresses that belong to the AF_INET addres family.
  503. X     */
  504. X
  505. X    if (sa.sa_family != AF_INET) {
  506. X    syslog(LOG_ERR, "unexpected address family %ld", (long) sa.sa_family);
  507. X    strcpy(f->source, "unknown");
  508. X    return (0);
  509. X    }
  510. X    if ((hp = gethostbyaddr((char *) &sin->sin_addr.s_addr,
  511. X                sizeof(sin->sin_addr.s_addr),
  512. X                AF_INET)) == 0) {
  513. X    strcpy(f->source, inet_ntoa(sin->sin_addr));    /* use address */
  514. X    return (0);
  515. X    }
  516. X
  517. X    /*
  518. X     * Save the host name, even if we may decide to not use it, because the
  519. X     * next gethostbyxxx() call will clobber it.
  520. X     */
  521. X
  522. X    strncpy(f->source, hp->h_name, sizeof(f->source) - 1);
  523. X    f->source[sizeof(f->source) - 1] = 0;
  524. X
  525. X    /*
  526. X     * Verify that the host name does not belong to someone else. If host
  527. X     * name verification fails, ignore the host name and use the address
  528. X     * instead.
  529. X     */
  530. X
  531. X    if (matchname(f->source, sin)) {
  532. X    return (0);
  533. X    } else {
  534. X    strcpy(f->source, inet_ntoa(sin->sin_addr));
  535. X    return (-1);                /* verification failed */
  536. X    }
  537. X}
  538. X
  539. X/* matchname - determine if host name matches IP address */
  540. X
  541. Xstatic int matchname(remotehost, sin)
  542. Xchar   *remotehost;
  543. Xstruct sockaddr_in *sin;
  544. X{
  545. X    struct hostent *hp;
  546. X    int     i;
  547. X
  548. X    if ((hp = gethostbyname(remotehost)) == 0) {
  549. X
  550. X    /*
  551. X     * Unable to verify that the host name matches the address. This may
  552. X     * be a transient problem or a botched name server setup. We decide
  553. X     * to play safe.
  554. X     */
  555. X
  556. X    syslog(LOG_ERR, "gethostbyname(%s): lookup failure", remotehost);
  557. X    return (BAD);
  558. X
  559. X    } else {
  560. X
  561. X    /* Look up the host address in the address list we just got. */
  562. X
  563. X    for (i = 0; hp->h_addr_list[i]; i++) {
  564. X        if (memcmp(hp->h_addr_list[i],
  565. X               (caddr_t) & sin->sin_addr,
  566. X               sizeof(sin->sin_addr)) == 0)
  567. X        return (GOOD);
  568. X    }
  569. X
  570. X    /*
  571. X     * The host name does not map to the original host address. Perhaps
  572. X     * someone has compromised a name server. More likely someone botched
  573. X     * it, but that could be dangerous, too.
  574. X     */
  575. X
  576. X    syslog(LOG_ERR, "host name/address mismatch: %s != %s",
  577. X           inet_ntoa(sin->sin_addr), hp->h_name);
  578. X    return (BAD);
  579. X    }
  580. X}
  581. X
  582. X#ifdef TEST
  583. X
  584. X/* Code for stand-alone testing. */
  585. X
  586. Xmain(argc, argv)
  587. Xint     argc;
  588. Xchar  **argv;
  589. X{
  590. X    struct from_host from;
  591. X
  592. X#ifdef LOG_MAIL
  593. X    (void) openlog(argv[0], LOG_PID, FACILITY);
  594. X#else
  595. X    (void) openlog(argv[0], LOG_PID);
  596. X#endif
  597. X    (void) fromhost(&from);
  598. X    printf("%s\n", from.source);
  599. X    return (0);
  600. X}
  601. X
  602. X#endif
  603. END_OF_FILE
  604.   if test 5501 -ne `wc -c <'fromhost.c'`; then
  605.     echo shar: \"'fromhost.c'\" unpacked with wrong size!
  606.   fi
  607.   # end of 'fromhost.c'
  608. fi
  609. if test -f 'hosts_access.5' -a "${1}" != "-c" ; then 
  610.   echo shar: Will not clobber existing file \"'hosts_access.5'\"
  611. else
  612.   echo shar: Extracting \"'hosts_access.5'\" \(5785 characters\)
  613.   sed "s/^X//" >'hosts_access.5' <<'END_OF_FILE'
  614. X.TH HOSTS_ACCESS 5
  615. X.ad
  616. X.fi
  617. X.SH NAME
  618. Xhosts_access \- host access control files
  619. X.SH DESCRIPTION
  620. X.ad
  621. X.fi
  622. XThis manual page describes a simple, but effective, access control
  623. Xfacility that is based on host (or domain) names, netgroups, internet
  624. Xaddresses (or network numbers) and on network daemon process names.
  625. X.PP
  626. XIn the following text, \fIdaemon\fP is the the process name (argv[0]
  627. Xvalue) of a network daemon process, and \fIclient\fP is the name of
  628. Xa remote host (or its internet address if the name is not available).
  629. X.IP o
  630. XAccess will be granted when a (daemon,client) pair is matched by an
  631. Xentry in the \fI/etc/hosts.allow\fP file.
  632. X.IP o
  633. XIf the previous test fails (perhaps because the \fIhosts.allow\fP file
  634. Xdoes not exist), access will be denied when a (daemon,client) pair is
  635. Xmatched by an entry in the \fI/etc/hosts.deny\fP file.
  636. X.IP o
  637. XIf the previous test fails (perhaps because the \fIhosts.deny\fP file
  638. Xdoes not exist), access will be granted.
  639. X.PP
  640. XA non-existing access control file is treated as if it were an empty
  641. Xfile. Thus, access control can be turned off by providing no access
  642. Xcontrol files.
  643. X.PP
  644. XThe format of the access control files is as follows.
  645. X.IP o
  646. XLines that begin with a `#\' character are ignored.
  647. X.IP o
  648. XOther lines should have the format (things between [] are optional):
  649. X.sp
  650. X.ti +3
  651. Xdaemon_list : client_list [ : shell_command ]
  652. X.PP
  653. X\fIdaemon_list\fP is a list of one or more daemon process names
  654. X(argv[0] values).  \fIclient_list\fP is a list of one or more host
  655. Xnames, domain names, netgroups, internet addresses or internet network
  656. Xnumbers.  List elements should be separated by blanks and/or commas.
  657. XWith the exception of netgroup lookups, all access control lookups are
  658. Xcase insensitive.
  659. X.PP
  660. XClient_list fields that specify a domain name should begin with a
  661. X`.\' character (see example below). Internet \fInetwork\fP numbers (as
  662. Xopposed to internet \fIhost\fP numbers) should be terminated with a `.\'
  663. Xcharacter. A netgroup name should begin with the `@\' character.
  664. XNetgroups are usually supported on systems with NIS (formerly YP)
  665. Xdata bases.
  666. X.PP
  667. XSpecial meaning is given to the magic token \fIALL\fP.  If it appears
  668. Xin a daemon_list, this token matches all network daemon process
  669. Xnames.  If the magic token appears in a client_list, it matches
  670. Xall clients.  Another token that receives special treatment is
  671. X\fILOCAL\fP. If it appears in a daemon_list or client_list,
  672. Xit matches any string that does not contain a dot character.
  673. X.PP
  674. XThe optional \fIshell_command\fP is executed if the table entry is the
  675. Xfirst one that matches the (daemon,client) pair. The format is: one or
  676. Xmore statements separated by a `;\' character. Prior to execution,
  677. Xthe following substitutions are done on the shell_command:
  678. X.TP
  679. X%h
  680. Xis replaced by the remote host name
  681. X(or address, if the host name is not available).
  682. X.TP
  683. X%d
  684. Xis replaced by the daemon process name (argv[0] value).
  685. X.TP
  686. X%p
  687. Xis replaced by the daemon process id.
  688. X.TP
  689. X%%
  690. Xis replaced by a single `%\' character.
  691. X.PP
  692. XThe resulting command is given to \fI/bin/sh\fP, with standard input,
  693. Xoutput and error connected to \fI/dev/null\fP.  Specify an `&\' at the
  694. Xend of the command if you do not want to wait until it has completed.
  695. X.PP
  696. XShell_commands should not rely on the PATH setting of the inetd.
  697. XInstead, they should use absolute path names, or they should begin with
  698. Xan explicit PATH=whatever statement.
  699. X.SH EXAMPLES
  700. XThe following example restricts all services to hosts within the local
  701. Xdomain (no `.\' character in the host name), all hosts below 
  702. Xthe \fI.some.domain\fP, and all hosts in the \fIthatgroup\fP netgroup:
  703. X.PP
  704. X/etc/hosts.allow: 
  705. X.in +3
  706. XALL: LOCAL, .some.domain, @thatgroup
  707. X.PP
  708. X/etc/hosts.deny: 
  709. X.in +3
  710. XALL: ALL
  711. X.PP
  712. XIn order to deny some hosts all services, except ftp:
  713. X.PP
  714. X/etc/hosts.allow: 
  715. X.in +3
  716. Xin.ftpd: ALL
  717. X.PP
  718. X/etc/hosts.deny: 
  719. X.in +3
  720. XALL: some.host.name, .some.domain
  721. X.PP
  722. XThe following example implements a backfinger facility that is
  723. Xtriggered when someone invokes your tftp service from a host outside the
  724. Xlocal domain:
  725. X.PP
  726. X/etc/hosts.allow:
  727. X.in +3
  728. X.nf
  729. Xin.tftpd: LOCAL, .my.domain
  730. X.PP
  731. X/etc/hosts.deny:
  732. X.in +3
  733. X.nf
  734. Xin.tftpd: ALL: (/bin/date; /usr/ucb/finger -l @%h) >>/var/adm/%d.log &
  735. X.fi
  736. X.PP
  737. XIf your tftp daemon is run under a uid other than root (strongly
  738. Xrecommended), the /var/adm/whatever.log file should be writable for
  739. Xthat uid. Watch out for infinite backfinger loops!
  740. X.SH DIAGNOSTICS
  741. X.ad
  742. X.fi
  743. XAn error is reported when a syntax error is found in a host access
  744. Xcontrol file; when the length of an entry in a host access control file
  745. Xexceeds the STDIO buffer size; when the result of %<character>
  746. Xexpansion would overflow an internal buffer; when a system call fails
  747. Xthat shouldn\'t.
  748. X.SH FILES
  749. X.na
  750. X.nf
  751. X/etc/hosts.allow, (daemon,client) pairs that are granted access.
  752. X/etc/hosts.deny, (daemon,client) pairs that are denied access.
  753. X.SH BUGS
  754. X.ad
  755. X.fi
  756. XIf there are problems with a name server, the access control software
  757. Xwill use a host\'s address instead of its name.  A workaround is to
  758. Xalso list internet addresses and network numbers in the access-control
  759. Xfiles.
  760. X.PP
  761. XDomain name server lookups are case insensitive; NIS (formerly YP)
  762. Xnetgroup lookups are case sensitive.
  763. X.PP
  764. XSome UDP (and RPC) daemons linger around for a while after they have
  765. Xfinished their work, just in case another request comes in (in the
  766. Xinetd configuration file, these daemons are registered with the `wait\'
  767. Xoption).  In such cases, access control will apply only to the request
  768. Xthat started such a daemon. This restriction usually does not apply to
  769. Xconnection-oriented (TCP) services.
  770. X.SH AUTHOR
  771. X.na
  772. X.nf
  773. XWietse Venema
  774. XEindhoven University of Technology
  775. XDepartment of Mathematics and Computer Science
  776. XDen Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  777. X\" @(#) hosts_access.5 1.8 91/10/02 23:02:00
  778. END_OF_FILE
  779.   if test 5785 -ne `wc -c <'hosts_access.5'`; then
  780.     echo shar: \"'hosts_access.5'\" unpacked with wrong size!
  781.   fi
  782.   # end of 'hosts_access.5'
  783. fi
  784. if test -f 'hosts_access.c' -a "${1}" != "-c" ; then 
  785.   echo shar: Will not clobber existing file \"'hosts_access.c'\"
  786. else
  787.   echo shar: Extracting \"'hosts_access.c'\" \(5582 characters\)
  788.   sed "s/^X//" >'hosts_access.c' <<'END_OF_FILE'
  789. X#ifdef HOSTS_ACCESS
  790. X
  791. X /*
  792. X  * This module implements a simple but effective form of access control
  793. X  * based on host (or domain) names, netgroup, internet addresses (or network
  794. X  * numbers) and daemon process names, with wild card support. Upon the first
  795. X  * match with an entry in the access-control tables, an optional shell
  796. X  * command is executed.
  797. X  * 
  798. X  * Diagnostics are reported through syslog(3).
  799. X  * 
  800. X  * Compile with -DHOSTS_ACCESS in order to enable access control. See the
  801. X  * hosts_access(5) manual page for details.
  802. X  * 
  803. X  * Compile with -DNETGROUP if your library provides support for netgroups.
  804. X  * 
  805. X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  806. X  */
  807. X
  808. X#ifndef lint
  809. Xstatic char sccsid[] = "@(#) hosts_access.c 1.6 91/10/02 23:01:49";
  810. X#endif
  811. X
  812. X /* System libraries. */
  813. X
  814. X#include <sys/types.h>
  815. X#include <sys/param.h>
  816. X#include <stdio.h>
  817. X#include <syslog.h>
  818. X#include <ctype.h>
  819. X
  820. Xextern char *fgets();
  821. Xextern char *strchr();
  822. Xextern char *strtok();
  823. Xextern void exit();
  824. X
  825. X/* Local stuff. */
  826. X
  827. X#include "log_tcp.h"
  828. X
  829. X/* Path names of the access control files. */
  830. X
  831. X#define HOSTS_ALLOW    "/etc/hosts.allow"
  832. X#define HOSTS_DENY    "/etc/hosts.deny"
  833. X
  834. X/* Delimiters for lists of daemons or clients. */
  835. X
  836. Xstatic char sep[] = ", \t";
  837. X
  838. X/* Constants to be used in assignments only, not in comparisons... */
  839. X
  840. X#define    YES        1
  841. X#define    NO        0
  842. X
  843. X/* Forward declarations. */
  844. X
  845. Xstatic int table_match();
  846. Xstatic int list_match();
  847. X
  848. X/* hosts_access - host access control facility */
  849. X
  850. Xint hosts_access(daemon, client)
  851. Xchar   *daemon;
  852. Xchar   *client;
  853. X{
  854. X
  855. X    /*
  856. X     * If the (daemon, client) pair is matched by an entry in the file
  857. X     * /etc/hosts.allow, access is granted. Otherwise, if the (daemon,
  858. X     * client) pair is matched by an entry in the file /etc/hosts.deny,
  859. X     * access is denied. Otherwise, access is granted. A non-existent
  860. X     * access-control file is treated as an empty file.
  861. X     */
  862. X
  863. X    if (table_match(HOSTS_ALLOW, daemon, client))
  864. X    return (YES);
  865. X    if (table_match(HOSTS_DENY, daemon, client)) 
  866. X    return (NO);
  867. X    return (YES);
  868. X}
  869. X
  870. X/* table_match - match table entries with (daemon, client) pair */
  871. X
  872. Xstatic int table_match(table, daemon, client)
  873. Xchar   *table;
  874. Xchar   *daemon;
  875. Xchar   *client;
  876. X{
  877. X    FILE   *fp;
  878. X    char    sv_list[BUFSIZ];        /* becomes list of daemons */
  879. X    char   *cl_list;            /* becomes list of clients */
  880. X    char   *sh_cmd;            /* becomes optional shell command */
  881. X    int     match = NO;
  882. X    int     end;
  883. X
  884. X    /*
  885. X     * Process the table one line at a time. Lines that begin with a '#'
  886. X     * character are ignored. Non-comment lines are broken at the ':'
  887. X     * character (we complain if there is none). The first field is matched
  888. X     * against the daemon process name (argv[0]), the second field against
  889. X     * the host name. A non-existing table is treated as if it were an empty
  890. X     * table. The optional shell command (third field) is executed when the
  891. X     * first match is found.
  892. X     */
  893. X
  894. X    if (fp = fopen(table, "r")) {
  895. X    while (match == 0 && fgets(sv_list, sizeof(sv_list), fp)) {
  896. X        if (sv_list[end = strlen(sv_list) - 1] != '\n') {
  897. X        syslog(LOG_ERR, "%s: line exceeds STDIO buffer size", table);
  898. X        continue;
  899. X        } else {
  900. X        sv_list[end] = '\0';        /* strip trailing newline */
  901. X        }
  902. X        if (sv_list[0] == '#') {        /* skip comments */
  903. X        continue;
  904. X        } else if ((cl_list = strchr(sv_list, ':')) == 0) {
  905. X        syslog(LOG_ERR, "%s: malformed entry: \"%s\"", table, sv_list);
  906. X        continue;
  907. X        } else {
  908. X        *cl_list++ = '\0';        /* split 1st and 2nd fields */
  909. X        if ((sh_cmd = strchr(cl_list, ':')) != 0)
  910. X            *sh_cmd++ = '\0';        /* split 2nd and 3rd fields */
  911. X        match = (list_match(sv_list, daemon)
  912. X             && list_match(cl_list, client));
  913. X        }
  914. X    }
  915. X    (void) fclose(fp);
  916. X    }
  917. X    if (match && sh_cmd)
  918. X    shell_cmd(sh_cmd, daemon, client);
  919. X    return (match);
  920. X}
  921. X
  922. X/* list_match - match a string against a list of tokens */
  923. X
  924. Xstatic int list_match(list, string)
  925. Xchar   *list;
  926. Xchar   *string;
  927. X{
  928. X    char   *tok;
  929. X    int     tok_len;
  930. X    int     str_len;
  931. X
  932. X    /*
  933. X     * Process tokens one at a time. If a token has the magic value "ALL" the
  934. X     * match always succeeds. If the token is a domain name, return YES if it
  935. X     * matches the last fields of the string. If the token has the magic
  936. X     * value "LOCAL", return YES if the string does not contain a "."
  937. X     * character. If the token is a network number, return YES if it matches
  938. X     * the head of the string. If the token looks like a netgroup name,
  939. X     * return YES if the string is a (host) member of the netgroup.
  940. X     * Otherwise, return YES if the token fully matches the string. Note: we
  941. X     * assume that a daemon process name never begins or ends with a "." or
  942. X     * "@" character.
  943. X     */
  944. X
  945. X    for (tok = strtok(list, sep); tok; tok = strtok((char *) 0, sep)) {
  946. X    if (tok[0] == '.') {            /* domain: match last fields */
  947. X        if ((str_len = strlen(string)) > (tok_len = strlen(tok))
  948. X        && strcasecmp(tok, string + str_len - tok_len) == 0)
  949. X        return (YES);
  950. X#ifdef    NETGROUP
  951. X    } else if (tok[0] == '@') {        /* netgroup: look it up */
  952. X        if (innetgr(tok + 1, string, (char *) 0, (char *) 0))
  953. X        return (YES);
  954. X#endif
  955. X    } else if (strcasecmp(tok, "ALL") == 0) {    /* all: match any */
  956. X        return (YES);
  957. X    } else if (strcasecmp(tok, "LOCAL") == 0) {    /* local: no dots */
  958. X        if (strchr(string, '.') == 0)
  959. X        return (YES);
  960. X    } else if (!strcasecmp(tok, string)) {    /* match host name or address */
  961. X        return (YES);
  962. X    } else if (tok[(tok_len = strlen(tok)) - 1] == '.'    /* net number */
  963. X           && strncmp(tok, string, tok_len) == 0) {
  964. X        return (YES);
  965. X    }
  966. X    }
  967. X    return (NO);
  968. X}
  969. X
  970. X#endif
  971. END_OF_FILE
  972.   if test 5582 -ne `wc -c <'hosts_access.c'`; then
  973.     echo shar: \"'hosts_access.c'\" unpacked with wrong size!
  974.   fi
  975.   # end of 'hosts_access.c'
  976. fi
  977. if test -f 'log_tcp.h' -a "${1}" != "-c" ; then 
  978.   echo shar: Will not clobber existing file \"'log_tcp.h'\"
  979. else
  980.   echo shar: Extracting \"'log_tcp.h'\" \(742 characters\)
  981.   sed "s/^X//" >'log_tcp.h' <<'END_OF_FILE'
  982. X/* @(#) log_tcp.h 1.1 91/10/02 23:01:55 */
  983. X
  984. X /*
  985. X  * Structure filled in by the fromhost() routine. Prerequisites:
  986. X  * <sys/types.h> and <sys/param.h>.
  987. X  */
  988. X
  989. X#ifndef MAXHOSTNAMELEN
  990. X#define MAXHOSTNAMELEN    1024
  991. X#endif
  992. X
  993. Xstruct from_host {
  994. X    int     sock_type;            /* socket type, see below */
  995. X    char    source[MAXHOSTNAMELEN + 1];    /* host name or address */
  996. X};
  997. X
  998. X/* Socket types: 0 means unknown. */
  999. X
  1000. X#define    FROM_CONNECTED        1    /* connection-oriented */
  1001. X#define    FROM_UNCONNECTED    2    /* non connection-oriented */
  1002. X
  1003. X/* Global functions. */
  1004. X
  1005. Xextern int fromhost();            /* get/validate remote host info */
  1006. Xextern int hosts_access();        /* access control */
  1007. Xextern void refuse();            /* refuse request */
  1008. Xextern void shell_cmd();        /* execute shell command */
  1009. END_OF_FILE
  1010.   if test 742 -ne `wc -c <'log_tcp.h'`; then
  1011.     echo shar: \"'log_tcp.h'\" unpacked with wrong size!
  1012.   fi
  1013.   # end of 'log_tcp.h'
  1014. fi
  1015. if test -f 'miscd.c' -a "${1}" != "-c" ; then 
  1016.   echo shar: Will not clobber existing file \"'miscd.c'\"
  1017. else
  1018.   echo shar: Extracting \"'miscd.c'\" \(2427 characters\)
  1019.   sed "s/^X//" >'miscd.c' <<'END_OF_FILE'
  1020. X /*
  1021. X  * Front end to the ULTRIX miscd service. The front end logs the remote host
  1022. X  * name and then invokes the real miscd daemon. Install as "/usr/etc/miscd",
  1023. X  * after moving the real miscd daemon to the "/usr/etc/..." directory.
  1024. X  * Connections and diagnostics are logged through syslog(3).
  1025. X  * 
  1026. X  * The Ultrix miscd program implements (among others) the systat service, which
  1027. X  * pipes the output from who(1) to stdout. This information is potentially
  1028. X  * useful to systems crackers.
  1029. X  * 
  1030. X  * Compile with -DHOSTS_ACCESS in order to enable access control. See the
  1031. X  * hosts_access(5) manual page for details.
  1032. X  * 
  1033. X  * Compile with -DPARANOID if service should be refused to hosts that pretend
  1034. X  * to have someone elses host name. This gives some protection against rsh
  1035. X  * and rlogin attacks that involve compromised domain name servers.
  1036. X  * 
  1037. X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  1038. X  */
  1039. X
  1040. X#ifndef lint
  1041. Xstatic char sccsid[] = "@(#) miscd.c 1.2 91/10/02 23:01:43";
  1042. X#endif
  1043. X
  1044. X/* System libraries. */
  1045. X
  1046. X#include <sys/types.h>
  1047. X#include <sys/param.h>
  1048. X#include <stdio.h>
  1049. X#include <syslog.h>
  1050. X
  1051. X/* Local stuff. */
  1052. X
  1053. X#include "log_tcp.h"
  1054. X
  1055. X/* The following specifies where the vendor-provided daemon should go. */
  1056. X
  1057. X#define REAL_DAEMON    "/usr/etc/.../miscd"
  1058. X
  1059. Xmain(argc, argv)
  1060. Xint     argc;
  1061. Xchar  **argv;
  1062. X{
  1063. X    struct from_host from;
  1064. X    int     from_stat;
  1065. X
  1066. X    /*
  1067. X     * Open a channel to the syslog daemon. Older versions of openlog()
  1068. X     * require only two arguments.
  1069. X     */
  1070. X
  1071. X#ifdef LOG_MAIL
  1072. X    (void) openlog(argv[0], LOG_PID, FACILITY);
  1073. X#else
  1074. X    (void) openlog(argv[0], LOG_PID);
  1075. X#endif
  1076. X
  1077. X    /*
  1078. X     * Find out and verify the remote host name. Sites concerned with
  1079. X     * security may choose to refuse connections from hosts that pretend to
  1080. X     * have someone elses host name.
  1081. X     */
  1082. X
  1083. X    from_stat = fromhost(&from);
  1084. X#ifdef PARANOID
  1085. X    if (from_stat == -1)
  1086. X    refuse(&from);
  1087. X#endif
  1088. X
  1089. X    /*
  1090. X     * Check whether this host can access the service in argv[0]. The
  1091. X     * access-control code invokes optional shell commands as specified in
  1092. X     * the access-control tables.
  1093. X     */
  1094. X
  1095. X#ifdef HOSTS_ACCESS
  1096. X    if (!hosts_access(argv[0], from.source))
  1097. X    refuse(&from);
  1098. X#endif
  1099. X
  1100. X    /* Report remote host name and invoke the real daemon program. */
  1101. X
  1102. X    syslog(LOG_INFO, "connect from %s", from.source);
  1103. X    (void) execv(REAL_DAEMON, argv);
  1104. X    syslog(LOG_ERR, "%s: %m", REAL_DAEMON);
  1105. X    return (1);
  1106. X}
  1107. END_OF_FILE
  1108.   if test 2427 -ne `wc -c <'miscd.c'`; then
  1109.     echo shar: \"'miscd.c'\" unpacked with wrong size!
  1110.   fi
  1111.   # end of 'miscd.c'
  1112. fi
  1113. if test -f 'refuse.c' -a "${1}" != "-c" ; then 
  1114.   echo shar: Will not clobber existing file \"'refuse.c'\"
  1115. else
  1116.   echo shar: Extracting \"'refuse.c'\" \(1368 characters\)
  1117.   sed "s/^X//" >'refuse.c' <<'END_OF_FILE'
  1118. X#if defined(PARANOID) || defined(HOSTS_ACCESS)
  1119. X
  1120. X /*
  1121. X  * refuse - do the necessary cleanup if we refuse service to some host. This
  1122. X  * code is never invoked when access control and protection against bad host
  1123. X  * names are disabled.
  1124. X  * 
  1125. X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  1126. X  */
  1127. X
  1128. X#ifndef lint
  1129. Xstatic char sccsid[] = "@(#) refuse.c 1.1 91/10/02 23:01:53";
  1130. X#endif
  1131. X
  1132. X/* System libraries. */
  1133. X
  1134. X#include <sys/types.h>
  1135. X#include <sys/param.h>
  1136. X#include <sys/socket.h>
  1137. X#include <netinet/in.h>
  1138. X#include <netdb.h>
  1139. X#include <stdio.h>
  1140. X#include <syslog.h>
  1141. X
  1142. Xextern void exit();
  1143. X
  1144. X/* Local stuff. */
  1145. X
  1146. X#include "log_tcp.h"
  1147. X
  1148. X/* refuse - refuse request from bad host */
  1149. X
  1150. Xvoid    refuse(f)
  1151. Xstruct from_host *f;
  1152. X{
  1153. X    char    buf[BUFSIZ];
  1154. X    struct sockaddr sa;
  1155. X    int     size = sizeof(sa);
  1156. X
  1157. X    syslog(LOG_WARNING, "refused connect from %s", f->source);
  1158. X
  1159. X    /*
  1160. X     * In the case of non-connection-oriented services we must discard the
  1161. X     * packet sent by the client. Otherwise, a fresh daemon will be started
  1162. X     * each time the present one exits. Some systems insist on a non-zero
  1163. X     * source address argument in the recvfrom() call below.
  1164. X     */
  1165. X
  1166. X    if (f->sock_type == FROM_UNCONNECTED)
  1167. X    (void) recvfrom(0, buf, sizeof(buf), 0, &sa, &size);
  1168. X
  1169. X    /* Terminate with zero exit status to keep the inetd happy. */
  1170. X
  1171. X    exit(0);
  1172. X}
  1173. X
  1174. X#endif
  1175. END_OF_FILE
  1176.   if test 1368 -ne `wc -c <'refuse.c'`; then
  1177.     echo shar: \"'refuse.c'\" unpacked with wrong size!
  1178.   fi
  1179.   # end of 'refuse.c'
  1180. fi
  1181. if test -f 'shell_cmd.c' -a "${1}" != "-c" ; then 
  1182.   echo shar: Will not clobber existing file \"'shell_cmd.c'\"
  1183. else
  1184.   echo shar: Extracting \"'shell_cmd.c'\" \(3723 characters\)
  1185.   sed "s/^X//" >'shell_cmd.c' <<'END_OF_FILE'
  1186. X#ifdef HOSTS_ACCESS
  1187. X
  1188. X /*
  1189. X  * shell_cmd() takes a shell command, performs %h (host name or address), %d
  1190. X  * (daemon name) and %p (daemon process id) substitutions and passes the
  1191. X  * result to /bin/sh, with standard input, standard output and standard
  1192. X  * error connected to /dev/null. This code is never called when host access
  1193. X  * control is disabled.
  1194. X  * 
  1195. X  * Diagnostics are reported through syslog(3).
  1196. X  * 
  1197. X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  1198. X  */
  1199. X
  1200. X#ifndef lint
  1201. Xstatic char sccsid[] = "@(#) shell_cmd.c 1.1 91/10/02 23:01:51";
  1202. X#endif
  1203. X
  1204. X/* System libraries. */
  1205. X
  1206. X#include <sys/types.h>
  1207. X#include <sys/param.h>
  1208. X#include <stdio.h>
  1209. X#include <syslog.h>
  1210. X
  1211. Xextern char *strcpy();
  1212. Xextern void closelog();
  1213. Xextern void exit();
  1214. X
  1215. X/* Local stuff. */
  1216. X
  1217. X#include "log_tcp.h"
  1218. X
  1219. X/* Forward declarations. */
  1220. X
  1221. Xstatic void do_percent();
  1222. Xstatic void do_child();
  1223. X
  1224. X/* shell_cmd - expand %<char> sequences and execute shell command */
  1225. X
  1226. Xvoid    shell_cmd(string, daemon, client)
  1227. Xchar   *string;
  1228. Xchar   *daemon;
  1229. Xchar   *client;
  1230. X{
  1231. X    char    cmd[BUFSIZ];
  1232. X    int     child_pid;
  1233. X    int     wait_pid;
  1234. X    int     daemon_pid = getpid();
  1235. X
  1236. X    /*
  1237. X     * Most of the work is done within the child process, to minimize the
  1238. X     * risk of damage to the parent.
  1239. X     */
  1240. X
  1241. X    switch (child_pid = fork()) {
  1242. X    case -1:                    /* error */
  1243. X    syslog(LOG_ERR, "fork: %m");
  1244. X    break;
  1245. X    case 00:                    /* child */
  1246. X    do_percent(cmd, sizeof(cmd), string, daemon, client, daemon_pid);
  1247. X    do_child(daemon, cmd);
  1248. X    /* NOTREACHED */
  1249. X    default:                    /* parent */
  1250. X    while ((wait_pid = wait((int *) 0)) != -1 && wait_pid != child_pid)
  1251. X         /* void */ ;
  1252. X    }
  1253. X}
  1254. X
  1255. X/* do_percent - do %<char> expansion, abort if result buffer is too small */
  1256. X
  1257. Xstatic void do_percent(result, result_len, str, daemon, client, pid)
  1258. Xchar   *result;
  1259. Xint     result_len;
  1260. Xchar   *str;
  1261. Xchar   *daemon;
  1262. Xchar   *client;
  1263. Xint     pid;
  1264. X{
  1265. X    char   *end = result + result_len - 1;    /* end of result buffer */
  1266. X    char   *expansion;
  1267. X    int     expansion_len;
  1268. X    char    pid_buf[10];
  1269. X
  1270. X    /*
  1271. X     * %h becomes the remote host name or address; %d the daemon process
  1272. X     * name; %p the daemon process id; %% becomes a %, and %other is ignored.
  1273. X     * We terminate with a diagnostic if we would overflow the result buffer.
  1274. X     */
  1275. X
  1276. X    while (*str) {
  1277. X    if (*str == '%') {
  1278. X        str++;
  1279. X        expansion =
  1280. X        *str == 'd' ? (str++, daemon) :
  1281. X        *str == 'h' ? (str++, client) :
  1282. X        *str == 'p' ? (str++, sprintf(pid_buf, "%d", pid), pid_buf) :
  1283. X        *str == '%' ? (str++, "%") :
  1284. X        *str == 0 ? "" : (str++, "");
  1285. X        expansion_len = strlen(expansion);
  1286. X        if (result + expansion_len >= end) {
  1287. X        syslog(LOG_ERR, "shell command too long: %30s...", result);
  1288. X        exit(0);
  1289. X        }
  1290. X        (void) strcpy(result, expansion);
  1291. X        result += expansion_len;
  1292. X    } else {
  1293. X        *result++ = *str++;
  1294. X    }
  1295. X    }
  1296. X    *result = 0;
  1297. X}
  1298. X
  1299. X/* do_child - exec command with { stdin, stdout, stderr } to /dev/null */
  1300. X
  1301. Xstatic void do_child(myname, command)
  1302. Xchar   *myname;
  1303. Xchar   *command;
  1304. X{
  1305. X    char   *error = 0;
  1306. X    int     tmp_fd;
  1307. X
  1308. X    /* Close a bunch of file descriptors. Ignore errors. */
  1309. X
  1310. X    closelog();
  1311. X    for (tmp_fd = 0; tmp_fd < 10; tmp_fd++)
  1312. X    (void) close(tmp_fd);
  1313. X
  1314. X    /* Set up new stdin, stdout, stderr, and exec the shell command. */
  1315. X
  1316. X    if (open("/dev/null", 2) != 0) {
  1317. X    error = "open /dev/null: %m";
  1318. X    } else if (dup(0) != 1 || dup(0) != 2) {
  1319. X    error = "dup: %m";
  1320. X    } else {
  1321. X    (void) execl("/bin/sh", "sh", "-c", command, (char *) 0);
  1322. X    error = "execl /bin/sh: %m";
  1323. X    }
  1324. X
  1325. X    /* We can reach the following code only if there was an error. */
  1326. X
  1327. X#ifdef LOG_MAIL
  1328. X    (void) openlog(myname, LOG_PID, FACILITY);
  1329. X#else
  1330. X    (void) openlog(myname, LOG_PID);
  1331. X#endif
  1332. X    syslog(LOG_ERR, error);
  1333. X    exit(0);
  1334. X}
  1335. X
  1336. X#endif
  1337. END_OF_FILE
  1338.   if test 3723 -ne `wc -c <'shell_cmd.c'`; then
  1339.     echo shar: \"'shell_cmd.c'\" unpacked with wrong size!
  1340.   fi
  1341.   # end of 'shell_cmd.c'
  1342. fi
  1343. if test -f 'strcasecmp.c' -a "${1}" != "-c" ; then 
  1344.   echo shar: Will not clobber existing file \"'strcasecmp.c'\"
  1345. else
  1346.   echo shar: Extracting \"'strcasecmp.c'\" \(3767 characters\)
  1347.   sed "s/^X//" >'strcasecmp.c' <<'END_OF_FILE'
  1348. X/*
  1349. X * Copyright (c) 1987 Regents of the University of California.
  1350. X * All rights reserved.
  1351. X *
  1352. X * Redistribution and use in source and binary forms are permitted
  1353. X * provided that the above copyright notice and this paragraph are
  1354. X * duplicated in all such forms and that any documentation,
  1355. X * advertising materials, and other materials related to such
  1356. X * distribution and use acknowledge that the software was developed
  1357. X * by the University of California, Berkeley.  The name of the
  1358. X * University may not be used to endorse or promote products derived
  1359. X * from this software without specific prior written permission.
  1360. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  1361. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  1362. X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  1363. X */
  1364. X
  1365. X#if defined(LIBC_SCCS) && !defined(lint)
  1366. Xstatic char sccsid[] = "@(#)strcasecmp.c    5.6 (Berkeley) 6/27/88";
  1367. X#endif /* LIBC_SCCS and not lint */
  1368. X
  1369. X#include <sys/types.h>
  1370. X
  1371. X/*
  1372. X * This array is designed for mapping upper and lower case letter
  1373. X * together for a case independent comparison.  The mappings are
  1374. X * based upon ascii character sequences.
  1375. X */
  1376. Xstatic u_char charmap[] = {
  1377. X    '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
  1378. X    '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
  1379. X    '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
  1380. X    '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
  1381. X    '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
  1382. X    '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
  1383. X    '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
  1384. X    '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
  1385. X    '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
  1386. X    '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
  1387. X    '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
  1388. X    '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
  1389. X    '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
  1390. X    '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
  1391. X    '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
  1392. X    '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
  1393. X    '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
  1394. X    '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
  1395. X    '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
  1396. X    '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
  1397. X    '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
  1398. X    '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
  1399. X    '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
  1400. X    '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
  1401. X    '\300', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
  1402. X    '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
  1403. X    '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
  1404. X    '\370', '\371', '\372', '\333', '\334', '\335', '\336', '\337',
  1405. X    '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
  1406. X    '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
  1407. X    '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
  1408. X    '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
  1409. X};
  1410. X
  1411. Xstrcasecmp(s1, s2)
  1412. X    char *s1, *s2;
  1413. X{
  1414. X    register u_char    *cm = charmap,
  1415. X            *us1 = (u_char *)s1,
  1416. X            *us2 = (u_char *)s2;
  1417. X
  1418. X    while (cm[*us1] == cm[*us2++])
  1419. X        if (*us1++ == '\0')
  1420. X            return(0);
  1421. X    return(cm[*us1] - cm[*--us2]);
  1422. X}
  1423. X
  1424. Xstrncasecmp(s1, s2, n)
  1425. X    char *s1, *s2;
  1426. X    register int n;
  1427. X{
  1428. X    register u_char    *cm = charmap,
  1429. X            *us1 = (u_char *)s1,
  1430. X            *us2 = (u_char *)s2;
  1431. X
  1432. X    while (--n >= 0 && cm[*us1] == cm[*us2++])
  1433. X        if (*us1++ == '\0')
  1434. X            return(0);
  1435. X    return(n < 0 ? 0 : cm[*us1] - cm[*--us2]);
  1436. X}
  1437. END_OF_FILE
  1438.   if test 3767 -ne `wc -c <'strcasecmp.c'`; then
  1439.     echo shar: \"'strcasecmp.c'\" unpacked with wrong size!
  1440.   fi
  1441.   # end of 'strcasecmp.c'
  1442. fi
  1443. if test -f 'tcpd.c' -a "${1}" != "-c" ; then 
  1444.   echo shar: Will not clobber existing file \"'tcpd.c'\"
  1445. else
  1446.   echo shar: Extracting \"'tcpd.c'\" \(2530 characters\)
  1447.   sed "s/^X//" >'tcpd.c' <<'END_OF_FILE'
  1448. X /*
  1449. X  * General front end for stream and datagram IP services. This program logs
  1450. X  * the remote host name and then invokes the real daemon. For example,
  1451. X  * install as /usr/etc/{tftpd,fingerd,telnetd,ftpd,rlogind,rshd,rexecd},
  1452. X  * after saving the real daemons in the directory "/usr/etc/...". This
  1453. X  * arrangement requires that the network daemons are started by inetd or
  1454. X  * something similar. Connections and diagnostics are logged through
  1455. X  * syslog(3).
  1456. X  * 
  1457. X  * Compile with -DHOSTS_ACCESS in order to enable access control. See the
  1458. X  * hosts_access(5) manual page for details.
  1459. X  * 
  1460. X  * Compile with -DPARANOID if service should be refused to hosts that pretend
  1461. X  * to have someone elses host name. This gives some protection against rsh
  1462. X  * and rlogin attacks that involve compromised domain name servers.
  1463. X  * 
  1464. X  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
  1465. X  */
  1466. X
  1467. X#ifndef lint
  1468. Xstatic char sccsid[] = "@(#) tcpd.c 1.2 91/10/02 23:01:44";
  1469. X#endif
  1470. X
  1471. X/* System libraries. */
  1472. X
  1473. X#include <sys/types.h>
  1474. X#include <sys/param.h>
  1475. X#include <stdio.h>
  1476. X#include <syslog.h>
  1477. X
  1478. X#ifndef MAXPATHNAMELEN
  1479. X#define MAXPATHNAMELEN    BUFSIZ
  1480. X#endif
  1481. X
  1482. X/* Local stuff. */
  1483. X
  1484. X#include "log_tcp.h"
  1485. X
  1486. X/* The following specifies where the vendor-provided daemons should go. */
  1487. X
  1488. X#define REAL_DAEMON_DIR    "/usr/etc/..."
  1489. X
  1490. Xmain(argc, argv)
  1491. Xint     argc;
  1492. Xchar  **argv;
  1493. X{
  1494. X    struct from_host from;
  1495. X    int     from_stat;
  1496. X    char    path[MAXPATHNAMELEN];
  1497. X
  1498. X    /*
  1499. X     * Open a channel to the syslog daemon. Older versions of openlog()
  1500. X     * require only two arguments.
  1501. X     */
  1502. X
  1503. X#ifdef LOG_MAIL
  1504. X    (void) openlog(argv[0], LOG_PID, FACILITY);
  1505. X#else
  1506. X    (void) openlog(argv[0], LOG_PID);
  1507. X#endif
  1508. X
  1509. X    /*
  1510. X     * Find out and verify the remote host name. Sites concerned with
  1511. X     * security may choose to refuse connections from hosts that pretend to
  1512. X     * have someone elses host name.
  1513. X     */
  1514. X
  1515. X    from_stat = fromhost(&from);
  1516. X#ifdef PARANOID
  1517. X    if (from_stat == -1)
  1518. X    refuse(&from);
  1519. X#endif
  1520. X
  1521. X    /*
  1522. X     * Check whether this host can access the service in argv[0]. The
  1523. X     * access-control code invokes optional shell commands as specified in
  1524. X     * the access-control tables.
  1525. X     */
  1526. X
  1527. X#ifdef HOSTS_ACCESS
  1528. X    if (!hosts_access(argv[0], from.source))
  1529. X    refuse(&from);
  1530. X#endif
  1531. X
  1532. X    /* Report remote host name and invoke the real daemon program. */
  1533. X
  1534. X    syslog(LOG_INFO, "connect from %s", from.source);
  1535. X    sprintf(path, "%s/%s", REAL_DAEMON_DIR, argv[0]);
  1536. X    (void) execv(path, argv);
  1537. X    syslog(LOG_ERR, "%s: %m", path);
  1538. X    return (1);
  1539. X}
  1540. END_OF_FILE
  1541.   if test 2530 -ne `wc -c <'tcpd.c'`; then
  1542.     echo shar: \"'tcpd.c'\" unpacked with wrong size!
  1543.   fi
  1544.   # end of 'tcpd.c'
  1545. fi
  1546. if test -f 'try.c' -a "${1}" != "-c" ; then 
  1547.   echo shar: Will not clobber existing file \"'try.c'\"
  1548. else
  1549.   echo shar: Extracting \"'try.c'\" \(818 characters\)
  1550.   sed "s/^X//" >'try.c' <<'END_OF_FILE'
  1551. X /*
  1552. X  * try - program to try out host access-control tables, including the
  1553. X  * optional shell commands.
  1554. X  * 
  1555. X  * usage: try process_name host_name
  1556. X  * 
  1557. X  * where process_name is a daemon process name (argv[0] value), and host_name
  1558. X  * is a host name or address.
  1559. X  * 
  1560. X  * Prints YES if access is granted, NO if denied.
  1561. X  */
  1562. X
  1563. X#include <stdio.h>
  1564. X#include <syslog.h>
  1565. X
  1566. Xmain(argc, argv)
  1567. Xint     argc;
  1568. Xchar  **argv;
  1569. X{
  1570. X#ifdef HOSTS_ACCESS
  1571. X
  1572. X#ifdef LOG_MAIL
  1573. X    openlog(argv[0], LOG_PID, FACILITY);
  1574. X#else
  1575. X    openlog(argv[0], LOG_PID);
  1576. X#endif
  1577. X
  1578. X    if (argc != 3) {
  1579. X    fprintf(stderr, "usage: %s process_name host_name\n", argv[0]);
  1580. X    return (1);
  1581. X    } else {
  1582. X    printf(hosts_access(argv[1], argv[2]) ? "YES\n" : "NO\n");
  1583. X    return (0);
  1584. X    }
  1585. X#else
  1586. X    fprintf(stderr, "host access control is not enabled.\n");
  1587. X    return (1);
  1588. X#endif
  1589. X}
  1590. END_OF_FILE
  1591.   if test 818 -ne `wc -c <'try.c'`; then
  1592.     echo shar: \"'try.c'\" unpacked with wrong size!
  1593.   fi
  1594.   # end of 'try.c'
  1595. fi
  1596. echo shar: End of archive 1 \(of 1\).
  1597. cp /dev/null ark1isdone
  1598. MISSING=""
  1599. for I in 1 ; do
  1600.     if test ! -f ark${I}isdone ; then
  1601.     MISSING="${MISSING} ${I}"
  1602.     fi
  1603. done
  1604. if test "${MISSING}" = "" ; then
  1605.     echo You have the archive.
  1606.     rm -f ark[1-9]isdone
  1607. else
  1608.     echo You still must unpack the following archives:
  1609.     echo "        " ${MISSING}
  1610. fi
  1611. exit 0
  1612. exit 0 # Just in case...
  1613. -- 
  1614. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1615. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1616. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1617. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1618.